package com.alone.wchat.common.net;

import com.alone.wchat.common.exception.AloneException;
import com.google.gson.Gson;
import org.apache.http.HttpEntity;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Http客户端工具类，封装HttpClient包中的类方法，提供HTTP get/post/delete/put
 * 
 * @author weirdor
 *
 */
public class HttpClientUtils {


    public static String genShortUrlFromSina(String link){
		String url = "http://api.t.sina.com.cn/short_url/shorten.json" +
				"?source=2928505742&url_long=#url_long#";
		url = url.replace("#url_long#", link);
		byte[] result = get(url, null);
		String jsonStr = new String(result);
		Gson gson = new Gson();
		List<Map<String, Object>> datas = gson.fromJson(jsonStr, List.class);
		Map<String, Object> data = datas.get(0);
		return data.get("url_short").toString();
	}

	/**
	 * 发送表单POST请求
	 * 
	 * @param url
	 *            请求url
	 * @param params
	 *            表单请求参数，没有可以为null
	 * @param headers
	 *            请求头 ，没有可以为null
	 * @param targetStatusCode
	 *            目标状态码
	 * @return 请求的响应体，具体处理逻辑有调用者决定
	 * @throws IOException
	 */
	public static byte[] post(String url, Map<String, String> params, Map<String, String> headers,
			int targetStatusCode) {

		try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
			HttpPost httpPost = new HttpPost(url);

			List<BasicNameValuePair> paramPairs = new ArrayList<BasicNameValuePair>();

			if (params != null) {
				for (Entry<String, String> entry : params.entrySet()) {
					paramPairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
				}
			}

			UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(paramPairs, "UTF-8");

			if (headers != null && headers.size() > 0) {
				for (Entry<String, String> header : headers.entrySet()) {
					httpPost.addHeader(header.getKey(), header.getValue());
				}
			}
			httpPost.setEntity(uefEntity);

			try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
				int responseCode = response.getStatusLine().getStatusCode();
				if (responseCode == targetStatusCode) {
					HttpEntity respEntity = response.getEntity();
					return EntityUtils.toByteArray(respEntity);
				} else {
					throw new AloneException( "发送请求失败，响应码：" + responseCode + "目标响应码：，"
							+ targetStatusCode + "，响应内容：" + response.toString(), responseCode);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new AloneException( "",e);
		}
	}

	/**
	 * 发送POST请求
	 * 
	 * @param url
	 *            请求url
	 * @param reqBody
	 *            请求体字符串
	 * @param headers
	 *            请求头 ，没有可以为null
	 * @param targetStatusCode
	 *            目标状态码
	 * @return 基本的字节数组，具体处理逻辑有调用者决定
	 * @throws IOException
	 */
	public static byte[] post(String url, String reqBody, Map<String, String> headers, int targetStatusCode) {

		try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
			HttpPost httpPost = new HttpPost(url);

			httpPost.setEntity(new StringEntity(reqBody, "utf-8"));

			if (headers != null && headers.size() > 0) {
				for (Entry<String, String> header : headers.entrySet()) {
					httpPost.addHeader(header.getKey(), header.getValue());
				}
			}
			CloseableHttpResponse response = httpclient.execute(httpPost);
			int responseCode = response.getStatusLine().getStatusCode();
			if (responseCode == targetStatusCode) {
				HttpEntity respEntity = response.getEntity();
				return EntityUtils.toByteArray(respEntity);
			} else {
				throw new  AloneException(
						"发送请求失败，响应码：" + responseCode + "目标响应码：，" + targetStatusCode + "，响应内容：" + response.toString(),
						responseCode);
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new  AloneException("",e);
		}
	}

	/**
	 * 发送PUT请求
	 * 
	 * @param url
	 *            请求url
	 * @param params
	 *            请求参数map，没有可以为null
	 * @param headers
	 *            请求头 ，没有可以为null
	 * @param targetStatusCode
	 *            目标状态码
	 * @return 请求的响应体，具体处理逻辑有调用者决定
	 * @throws IOException
	 */
	public static byte[] put(String url, Map<String, String> params, Map<String, String> headers,
			int targetStatusCode) {

		try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
			HttpPut httpPut = new HttpPut(url);

			List<BasicNameValuePair> paramPairs = new ArrayList<BasicNameValuePair>();

			if (params != null) {
				for (Entry<String, String> entry : params.entrySet()) {
					paramPairs.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
				}
			}

			UrlEncodedFormEntity uefEntity = new UrlEncodedFormEntity(paramPairs, "UTF-8");

			if (headers != null && headers.size() > 0) {
				for (Entry<String, String> header : headers.entrySet()) {
					httpPut.addHeader(header.getKey(), header.getValue());
				}
			}
			httpPut.setEntity(uefEntity);

			try (CloseableHttpResponse response = httpclient.execute(httpPut)) {
				int responseCode = response.getStatusLine().getStatusCode();
				if (responseCode == targetStatusCode) {
					HttpEntity respEntity = response.getEntity();
					return EntityUtils.toByteArray(respEntity);
				} else {
					throw new  AloneException( "发送请求失败，响应码：" + responseCode + "目标响应码：，"
							+ targetStatusCode + "，响应内容：" + response.toString(), responseCode);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new  AloneException("",e);
		}
	}

	/**
	 * 发送PUT请求
	 * 
	 * @param url
	 *            请求url
	 * @param params
	 *            请求参数字符串
	 * @param headers
	 *            请求头 ，没有可以为null
	 * @param targetStatusCode
	 *            目标状态码
	 * @return 请求的响应体，具体处理逻辑有调用者决定
	 * @throws IOException
	 */
	public static byte[] put(String url, String params, Map<String, String> headers, int targetStatusCode) {

		try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
			HttpPut httpPut = new HttpPut(url);

			httpPut.setEntity(new StringEntity(params, "utf-8"));

			if (headers != null && headers.size() > 0) {
				for (Entry<String, String> header : headers.entrySet()) {
					httpPut.addHeader(header.getKey(), header.getValue());
				}
			}

			try (CloseableHttpResponse response = httpclient.execute(httpPut)) {
				int responseCode = response.getStatusLine().getStatusCode();
				if (responseCode == targetStatusCode) {
					HttpEntity respEntity = response.getEntity();
					return EntityUtils.toByteArray(respEntity);
				} else {
					throw new  AloneException("发送请求失败，响应码：" + responseCode + "目标响应码：，"
							+ targetStatusCode + "，响应内容：" + response.toString(), responseCode);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new  AloneException(""+e);
		}
	}

	public static byte[] get(String url, Map<String, String> headers) {

		try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
			HttpGet httpGet = new HttpGet(url);

			if (headers != null && headers.size() > 0) {
				for (Entry<String, String> header : headers.entrySet()) {
					httpGet.addHeader(header.getKey(), header.getValue());
				}
			}

			try (CloseableHttpResponse response = httpclient.execute(httpGet)) {
				int responseCode = response.getStatusLine().getStatusCode();
				if (responseCode == 200) {
					HttpEntity respEntity = response.getEntity();
					return EntityUtils.toByteArray(respEntity);
				} else {
					throw new  AloneException(
							"发送请求失败，响应码：" + responseCode + "目标响应码：200，响应内容：" + response.toString(), responseCode);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new  AloneException(""+e);
		}
	}

	public static byte[] delete(String url) {

		try (CloseableHttpClient httpclient = HttpClients.createDefault()) {
			HttpDelete httpDelete = new HttpDelete(url);

			try (CloseableHttpResponse response = httpclient.execute(httpDelete)) {
				int responseCode = response.getStatusLine().getStatusCode();
				if (response.getStatusLine().getStatusCode() == 200) {
					HttpEntity respEntity = response.getEntity();
					return EntityUtils.toByteArray(respEntity);
				} else {
					throw new  AloneException(
							"发送请求失败，响应码：" + responseCode + "目标响应码：200，响应内容：" + response.toString(), responseCode);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new  AloneException("",e);
		}
	}

}
